home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / cli / mcomms_1_4.lha / Src / bootlog.c next >
C/C++ Source or Header  |  1995-08-24  |  5KB  |  180 lines

  1. /*
  2. **    bootlog.c - record reason/date/time of system boot
  3. **    Copyright ⌐ 1995 Michael Letowski
  4. */
  5.  
  6. #define __USE_SYSBASE
  7.  
  8. #include <exec/types.h>
  9. #include <exec/execbase.h>
  10. #include <exec/memory.h>
  11. #include <dos/dos.h>
  12. #include <dos/datetime.h>
  13. #include <dos/rdargs.h>
  14. #include <support/types.h>
  15. #include <support/exec.h>
  16. #include <support/dos.h>
  17.  
  18. #include <string.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22.  
  23. #include "bootlog.rev.h"
  24.  
  25. #define DOS_NAME        "dos.library"
  26. #define DOS_VERN        37L
  27.  
  28. #define TEMPLATE        "LOGFILE,QUIET/S"
  29.  
  30. /* Boot reasons */
  31. #define BOOT_ALERT        0
  32. #define BOOT_POWER        1
  33. #define BOOT_RESET        2
  34. #define BOOT_COUNT        3
  35.  
  36. /* Defaults */
  37. #define DEF_LOGFILE            "DEVS:Logs/Boot.log"
  38. #define LOG_FORMAT            "%s: %s %s %s\n"
  39.  
  40. #define PStr(arg,def)        (*(arg)=='\0' ? (def) : (arg))
  41.  
  42. STATIC CONST TEXT VersionString[]=
  43.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  44.  
  45. struct Options
  46. {
  47.     STRPTR  opt_LogFile;
  48.     LONG    opt_Quiet;
  49. };    /* Options */
  50.  
  51. struct FormatData
  52. {
  53.     STRPTR fd_Reason;
  54.     STRPTR fd_Day;
  55.     STRPTR fd_Date;
  56.     STRPTR fd_Time;
  57. };    /* FormatData */
  58.  
  59. STATIC struct MemList *FindKickMem(STRPTR name);
  60. STATIC struct MemList *AddKickMem(STRPTR name);
  61.  
  62. LONG BootLog(VOID)
  63. {
  64.     STATIC CONST STRPTR BootReasons[BOOT_COUNT]=
  65.     {
  66.         "Alert","Power","Reset"
  67.     };    /* BootReasons */
  68.  
  69.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  70.     struct DosLibrary *DOSBase;
  71.  
  72.     CHAR StrDay[LEN_DATSTRING], StrDate[LEN_DATSTRING], StrTime[LEN_DATSTRING];
  73.  
  74.     struct Options Opts;
  75.     struct DateTime DT;
  76.     struct FormatData Data;
  77.     struct RDArgs *Args;
  78.     STRPTR LogFile;
  79.     BPTR FH;
  80.     LONG Boot,RC=RETURN_FAIL;
  81.  
  82.     /* Open DOS */
  83.     unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
  84.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY),    NO_DOS);
  85.  
  86.     /* Read arguments */
  87.     clear(&Opts);                                                                    /* Clear out buffer */
  88.     unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
  89.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_ARGS);
  90.     LogFile=Opts.opt_LogFile ? Opts.opt_LogFile : (STRPTR)DEF_LOGFILE;
  91.  
  92.     RC=RETURN_ERROR;                                                            /* Working a bit */
  93.  
  94.     /* Find cause of reboot */
  95.     Forbid();
  96.     if(FindKickMem(PROJ_NAME))                                        /* Tag found */
  97.         Boot=BOOT_RESET;                                                        /* So this is reset */
  98.     else                                                                                    /* Tag not found */
  99.         AddKickMem(PROJ_NAME),    Boot=BOOT_POWER;        /* Add it - this power on */
  100.     if(SysBase->LastAlert[1])                                            /* Guru? */
  101.         Boot=BOOT_ALERT;                                                        /* This is alert */
  102.     Permit();
  103.  
  104.     /* Set up date conversion struct */
  105.     DateStamp(&DT.dat_Stamp);                                            /* Get current date & time */
  106.     DT.dat_Format=FORMAT_DOS;                                            /* ADOS default format */
  107.     DT.dat_Flags=DTF_FUTURE;                                            /* Mark 'future' events */
  108.     DT.dat_StrDay=StrDay;                                                    /* Set up string buffers */
  109.     DT.dat_StrDate=StrDate;
  110.     DT.dat_StrTime=StrTime;
  111.     /* Convert date */
  112.     unless(DateToStr(&DT))                                                /* Conversion unsuccessfull */
  113.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_DATE);
  114.  
  115.     /* Set up data for formatting */
  116.     Data.fd_Reason=BootReasons[Boot];                            /* Set up reason */
  117.     Data.fd_Day=DT.dat_StrDay;                                        /* And dates */
  118.     Data.fd_Date=DT.dat_StrDate;
  119.     Data.fd_Time=DT.dat_StrTime;
  120.     
  121.     if(FH=Open(LogFile,MODE_READWRITE))                        /* Open log file for appending */
  122.     {
  123.         if(Seek(FH,0,OFFSET_END)>=0)                                /* Seeked to end */
  124.             if(VFPrintf(FH,LOG_FORMAT,&Data)>=0)            /* FPrintf successfull */
  125.                 RC=RETURN_OK;                                                        /* Success */
  126.             else                                                                            /* FPrintf unsuccessfull */
  127.                 PrintFault(IoErr(),PROG_NAME);                    /* Inform user */
  128.         else                                                                                /* Seek unsuccessfull */
  129.             PrintFault(IoErr(),PROG_NAME);                        /* Infor user */
  130.         Close(FH);                                                                    /* Close file */
  131.     }
  132.     else                                                                                    /* Couldn't open file */
  133.         PrintFault(IoErr(),PROG_NAME);                            /* Inform user */
  134.  
  135.     unless(Opts.opt_Quiet)                                                /* 'Loud' mode */
  136.         VPrintf(LOG_FORMAT,&Data);                                    /* Print to stdout, too */
  137.  
  138.     catch(NO_DATE,    );
  139.     catch(NO_ARGS,    FreeArgs(Args));
  140.     catch(NO_DOS,        CloseLibrary((struct Library *)DOSBase));
  141.     return(RC);
  142. }    /* BootLog */
  143.  
  144. STATIC struct MemList *FindKickMem(STRPTR name)
  145. {
  146.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  147.     struct MemList *Curr;
  148.  
  149.     Curr=SysBase->KickMemPtr;
  150.     while(Curr && strcmp(Curr->ml_Node.ln_Name,name))
  151.         Curr=Succ(&Curr->ml_Node);
  152.     return(Curr);
  153. }    /* FindKickMem */
  154.  
  155. STATIC struct MemList *AddKickMem(STRPTR name)
  156. {
  157.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  158.     struct MemList *ML;
  159.     struct Node *Node;
  160.     ULONG Size=sizeof(struct MemList)+strlen(name)+1;
  161.  
  162.     if(ML=AllocMem(Size,MEMF_KICK | MEMF_CLEAR))    /* Get Kick-able memory */
  163.     {
  164.         /* Initialize */
  165.         ML->ml_Node.ln_Type=NT_KICKMEM;
  166.         ML->ml_Node.ln_Name=(STRPTR)ML+sizeof(struct MemList);
  167.         strcpy(ML->ml_Node.ln_Name,name);
  168.         ML->ml_NumEntries=1;
  169.         ML->ml_ME[0].me_Addr=ML;
  170.         ML->ml_ME[0].me_Length=Size;
  171.         /* Link into exec */
  172.         if(Node=(ML->ml_Node.ln_Succ=SysBase->KickMemPtr))
  173.             Node->ln_Pred=&ML->ml_Node;
  174.         SysBase->KickMemPtr=ML;
  175.         SysBase->KickCheckSum=(APTR)SumKickData();
  176.         CacheClearU();                                                            /* As documented in AutoDocs */
  177.     }
  178.     return(ML);
  179. }    /* AddKickMem */
  180.